package com.ganlucode.sipmock.sip.request.impl;

import com.ganlucode.sipmock.config.SipServerProperties;
import com.ganlucode.sipmock.gb28181.sdp.SdpFactoryGB28181;
import com.ganlucode.sipmock.gb28181.sdp.SessionDescriptionGB28181;
import com.ganlucode.sipmock.sip.request.ISipRequestProcessor;
import com.ganlucode.sipmock.sip.request.SipRequestFactory;
import com.ganlucode.sipmock.utils.SipHelper;
import gov.nist.javax.sdp.fields.AttributeField;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sdp.MediaDescription;
import javax.sdp.Origin;
import javax.sip.RequestEvent;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.ViaHeader;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.util.Properties;
import java.util.Vector;

/**
 * @author GanLu
 */
@Slf4j
@Service("inviteRequestProcessor")
public class InviteRequestProcessor implements ISipRequestProcessor {

	@Autowired
	private SipHelper sipHelper;

	@Autowired
	private MessageFactory messageFactory;
	@Autowired
	private SipServerProperties sipServerProperties;
	@Autowired
	private SipRequestFactory sipRequestFactory;
	@Autowired
	private HeaderFactory headerFactory;

	private SdpFactoryGB28181 sdpFactory = SdpFactoryGB28181.getInstance();


	/**
	 * 处理invite请求
	 *
	 */ 
	@Override
	public void process(RequestEvent requestEvent) throws Exception {
		log.info("InviteRequestProcessor:处理invite请求");
		Request request = requestEvent.getRequest();
		Properties sdp = new Properties();
		InputStream is = new ByteArrayInputStream((byte[]) request.getContent());
		sdp.load(is);

		// 发送100 Trying
		Response responseTrying = createResponse(Response.TRYING, request);
		log.info("Invite请求，回复Trying");
		sipHelper.getSipProvider().sendResponse(responseTrying);

//		requestEvent.getDialog().sendReliableProvisionalResponse(responseTrying);

//		ServerTransaction serverTransaction = sipHelper.createServerTransaction(requestEvent);
//		// 查询目标地址
//		URI reqUri = request.getRequestURI();
//		URI contactURI = ((ContactHeader) request.getHeader("Contact")).getAddress().getURI();
//
//		System.out.println("processInvite rqStr=" + reqUri + " contact=" + contactURI);
//
//		// 根据Request uri来路由，后续的响应消息通过VIA来路由
//		Request cliReq = messageFactory.createRequest(request.toString());
//		cliReq.setRequestURI(contactURI);
//
////		HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory();
//		Via callerVia = (Via) request.getHeader(Via.NAME);
//		Via via = (Via) headerFactory.createViaHeader(SIPMain.ip, SIPMain.port, "UDP",
//				callerVia.getBranch() + "sipphone");
//
//		// FIXME 需要测试是否能够通过设置VIA头域来修改VIA头域值
//		cliReq.removeHeader(Via.NAME);
//		cliReq.addHeader(via);
//
//		// 更新contact的地址
//		ContactHeader contactHeader = headerFactory.createContactHeader();
//		Address address = SipFactory.getInstance().createAddressFactory()
//				.createAddress("sip:sipsoft@" + SIPMain.ip + ":" + SIPMain.port);
//		contactHeader.setAddress(address);
//		contactHeader.setExpires(3600);
//		cliReq.setHeader(contactHeader);
//
//		ClientTransaction clientTransactionId = sipHelper.getSipProvider().getNewClientTransaction(cliReq);
//		clientTransactionId.sendRequest();
//
//		System.out.println("processInvite clientTransactionId=" + clientTransactionId.toString());
//
//		System.out.println("send invite to callee: " + cliReq);
		SessionDescriptionGB28181 sessionDescription = (SessionDescriptionGB28181) sdpFactory
				.createSessionDescription(new String((byte[]) request.getContent()));
//		System.out.println(sessionDescription.getSsrcField().getSsrc());


		//OK
		Response responseOk = createResponse(Response.OK, request);
		responseOk.addHeader(sipRequestFactory.createContactHeader());
		String transport = sipHelper.getTransport();
//		StringBuilder content = new StringBuilder();
//		content.append("v=0\r\n");
//		content.append("o="+sipServerProperties.getSipServerId()+" 0 0 IN IP4 "+sipServerProperties.getSipIp()+"\r\n");
//		content.append("s=Play\r\n");
//		content.append("c=IN IP4 "+sipServerProperties.getSipIp()+"\r\n");
//		content.append("t=0 0\r\n");
//		if("TCP".equalsIgnoreCase(transport)) {
//			content.append("m=video 15060 TCP/RTP/AVP 96\r\n");
//		}
//		if("UDP".equalsIgnoreCase(transport)) {
//			content.append("m=video 15060 RTP/AVP 96\r\n");
//		}
//		content.append("a=setup:active\r\n");
//		content.append("a=sendonly\r\n");
//		content.append("a=rtpmap:96 PS/90000\r\n");
//		content.append("a=username:"+sipServerProperties.getSipServerId()+"\r\n");
//		content.append("a=password:"+sipServerProperties.getSipPassword()+"\r\n");
//		content.append("a=filesize:0\r\n");
//		content.append("y="+sdp.getProperty("y")+"\r\n");
//		content.append("f=");

		SessionDescriptionGB28181 okContent = new SessionDescriptionGB28181();
		okContent.setVersion(sessionDescription.getVersion());
		Origin origin = sdpFactory.createOrigin(sipServerProperties.getSipServerId(),sipServerProperties.getSipIp());
		origin.setSessionId(0);
		origin.setSessionVersion(0);
		okContent.setOrigin(origin);
		okContent.setSessionName(sessionDescription.getSessionName());
		okContent.setConnection(sdpFactory.createConnection(sipServerProperties.getSipIp()));
		okContent.setTimeDescriptions(sessionDescription.getTimeDescriptions(true));
		String mediaTransport = null;
		if("TCP".equalsIgnoreCase(transport)) {
			mediaTransport = "TCP/RTP/AVP";
		}
		if("UDP".equalsIgnoreCase(transport)) {
			mediaTransport = "RTP/AVP";
		}
		MediaDescription media = sdpFactory.createMediaDescription("video",15060,0,mediaTransport, new int[]{96});
		media.addAttribute((AttributeField) sdpFactory.createAttribute("setup","active"));
		media.addAttribute((AttributeField) sdpFactory.createAttribute("sendonly",null));
		media.addAttribute((AttributeField) sdpFactory.createAttribute("rtpmap","96 PS/90000"));
		media.addAttribute((AttributeField) sdpFactory.createAttribute("username",sipServerProperties.getSipServerId()));
		media.addAttribute((AttributeField) sdpFactory.createAttribute("password",sipServerProperties.getSipPassword()));
		media.addAttribute((AttributeField) sdpFactory.createAttribute("filesize","0"));
		Vector medias = new Vector();
		medias.add(media);
		okContent.setMediaDescriptions(medias);
		okContent.setSsrcField(sessionDescription.getSsrcField());



//		System.out.println(content.toString());
		ContentTypeHeader contentTypeHeader = headerFactory.createContentTypeHeader("Application", "sdp");
		responseOk.setContent(okContent.toString(),contentTypeHeader);
		log.info("Invite请求，回复OK");
		sipHelper.getSipProvider().sendResponse(responseOk);
//		requestEvent.getDialog().sendReliableProvisionalResponse(responseOk);
		log.info("请求Invite实时视频成功");



	}

	private Response createResponse(Integer status,Request request) throws ParseException {
		Response response = messageFactory.createResponse(status, request);
		response.addHeader(sipRequestFactory.createUserAgentHeader());
//		re
//		response.addHeader(request.getHeader(ContactHeader.NAME));
		ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
		viaHeader.removeParameter("received");
		return response;
	}

}
